/**
 * 本地存储工具类
 * 封装 localStorage，提供类型安全和统一的错误处理
 */

/**
 * 存储键名枚举
 * 统一管理所有存储键名，避免硬编码和键名冲突
 */
export enum StorageKey {
  /** 用户认证 Token */
  AUTH_TOKEN = 'auth_token',
  /** 用户信息 */
  USER_INFO = 'user_info',
  /** 用户菜单 */
  USER_MENUS = 'user_menus',
  /** 用户权限 */
  USER_PERMISSIONS = 'user_permissions',
  /** 刷新 Token */
  REFRESH_TOKEN = 'refresh_token',
  /** 语言设置 */
  LANGUAGE = 'language',
  /** 主题设置 */
  THEME = 'theme',
  /** 侧边栏折叠状态 */
  SIDEBAR_COLLAPSED = 'sidebar_collapsed',
  /** 表格列配置 */
  TABLE_COLUMNS = 'table_columns',
  /** 搜索历史 */
  SEARCH_HISTORY = 'search_history',
}

/**
 * 存储配置
 */
interface StorageConfig {
  /** 键名前缀，避免与其他应用冲突 */
  prefix?: string;
}

/**
 * 本地存储类
 */
class Storage {
  private prefix: string;

  constructor(config: StorageConfig = {}) {
    this.prefix = config.prefix || 'nbase_';
  }

  /**
   * 获取完整的存储键名
   */
  private getFullKey(key: StorageKey | string): string {
    return `${this.prefix}${key}`;
  }

  /**
   * 设置存储项
   * @param key 存储键
   * @param value 存储值（自动序列化为 JSON）
   * @returns 是否设置成功
   */
  set<T = any>(key: StorageKey | string, value: T): boolean {
    try {
      const fullKey = this.getFullKey(key);
      const serializedValue = JSON.stringify(value);
      localStorage.setItem(fullKey, serializedValue);
      return true;
    } catch (error) {
      console.error(`[Storage] 设置存储失败 [${key}]:`, error);
      return false;
    }
  }

  /**
   * 获取存储项
   * @param key 存储键
   * @param defaultValue 默认值（当键不存在或解析失败时返回）
   * @returns 存储值（自动反序列化）
   */
  get<T = any>(key: StorageKey | string, defaultValue?: T): T | null {
    try {
      const fullKey = this.getFullKey(key);
      const serializedValue = localStorage.getItem(fullKey);

      if (serializedValue === null) {
        return defaultValue !== undefined ? defaultValue : null;
      }

      return JSON.parse(serializedValue) as T;
    } catch (error) {
      console.error(`[Storage] 获取存储失败 [${key}]:`, error);
      return defaultValue !== undefined ? defaultValue : null;
    }
  }

  /**
   * 移除存储项
   * @param key 存储键
   * @returns 是否移除成功
   */
  remove(key: StorageKey | string): boolean {
    try {
      const fullKey = this.getFullKey(key);
      localStorage.removeItem(fullKey);
      return true;
    } catch (error) {
      console.error(`[Storage] 移除存储失败 [${key}]:`, error);
      return false;
    }
  }

  /**
   * 清空所有存储项（仅清空带前缀的项）
   * @returns 是否清空成功
   */
  clear(): boolean {
    try {
      const keys = Object.keys(localStorage);
      keys.forEach(key => {
        if (key.startsWith(this.prefix)) {
          localStorage.removeItem(key);
        }
      });
      return true;
    } catch (error) {
      console.error('[Storage] 清空存储失败:', error);
      return false;
    }
  }

  /**
   * 检查存储项是否存在
   * @param key 存储键
   * @returns 是否存在
   */
  has(key: StorageKey | string): boolean {
    const fullKey = this.getFullKey(key);
    return localStorage.getItem(fullKey) !== null;
  }

  /**
   * 获取所有存储键（仅返回带前缀的键）
   * @returns 存储键数组
   */
  keys(): string[] {
    const keys = Object.keys(localStorage);
    return keys
      .filter(key => key.startsWith(this.prefix))
      .map(key => key.replace(this.prefix, ''));
  }

  /**
   * 获取存储项数量（仅统计带前缀的项）
   * @returns 存储项数量
   */
  size(): number {
    return this.keys().length;
  }
}

/**
 * 默认存储实例
 */
export const storage = new Storage({ prefix: 'nbase_' });

/**
 * 导出 Storage 类，允许创建自定义实例
 */
export { Storage };

